package com.example.demo.common;

import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.example.demo.common.anno.UserRole;
import com.example.demo.entity.SessionStorage;
import com.example.demo.entity.SysUser;
import com.example.demo.exception.CustomException;
import com.example.demo.mapper.SysUserMapper;
import com.example.demo.utils.JWTUtil;
import com.example.demo.utils.RedisUtil;
import com.example.demo.utils.UserInfoUtil;
import com.example.demo.utils.enu.UserInfoEnu;
import com.example.demo.utils.enu.UserRoleEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.text.MessageFormat;

public class AuthInterceptor implements HandlerInterceptor {

    @Resource
    private SysUserMapper userMapper;
    @Autowired
    private RedisUtil redisUtil;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {

        //获取request对应controller方法
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        String token = request.getHeader("token");
        if (StrUtil.isBlank(token)) {
            throw new CustomException("401", "未获取到token, 请重新登录");
        }
        DecodedJWT decodedJWT = JWTUtil.getTokenInfo(token);
        String userId = decodedJWT.getClaim("userId").asString();
        String username = decodedJWT.getClaim("username").asString();
        String role = decodedJWT.getClaim("role").asString();
        SessionStorage sessionStorage = (SessionStorage) redisUtil.get(MessageFormat.format("SessionStorage_{0}_{1}", new Object[]{userId, username}));
        if (sessionStorage == null) {
            throw new CustomException("401", "token不合法");
        }
        UserInfoUtil.set("userId", String.valueOf(userId));
        UserInfoUtil.set("username", username);
        UserInfoUtil.set("role", role);
        //获取注解内容
        UserRole clazzRole = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(),UserRole.class);
        UserRole methodRole = AnnotationUtils.findAnnotation(method,UserRole.class);
        if (clazzRole==null&&methodRole==null){
            return true;
        }
        UserRoleEnum[] roleEnums;
        if (clazzRole!=null&&methodRole==null){
            roleEnums = clazzRole.value();
        }else if (clazzRole==null){
            roleEnums = methodRole.value();
        }else {
            roleEnums = methodRole.value();
        }
        if (!roleCheck(roleEnums,role)){
            throw new CustomException("402", "权限不足");
        }
        return true;
    }
    //根据注解鉴权
    public boolean roleCheck(UserRoleEnum[] roleEnum,String role){
        for (UserRoleEnum userRoleEnum:roleEnum){
            if (userRoleEnum.getValue().equals(role)){
               return true;
            }
        }
        return false;
    }

}
